<template>
  <div class="goods-sku">
    <dl v-for="(item, index) in specs" :key="index">
      <!-- 规格类型 -->
      <dt>{{ item.name }}</dt>
      <dd>
        <template v-for="(tag, i) in item.values" :key="i">
          <!-- 规格下的选项：图片或者文字 -->
          <img
            @click="toggle(tag, item.values)"
            :class="{ selected: tag.selected, disabled: tag.disabled }"
            v-if="tag.picture"
            :src="tag.picture"
            alt=""
          />
          <span @click="toggle(tag, item.values)" :class="{ selected: tag.selected, disabled: tag.disabled }" v-else>{{
            tag.name
          }}</span>
        </template>
      </dd>
    </dl>
  </div>
</template>
<script>
import powerSet from '@/vender/power-set.js'
const spliter = '#'
// 生成路径字典
const usePathMap = skus => {
  // 最终的字典
  const pathMap = {}
  skus.forEach(sku => {
    // 过滤掉库存为0的sku
    if (sku.inventory === 0) return
    // 把sku中的规格数据转换为普通数组
    // attrs = [蓝色，中国，10cm]
    const attrs = sku.specs.map(item => item.valueName)
    // 计算集合的笛卡尔集
    const subsets = powerSet(attrs)
    // 把集合转换为字典
    subsets.forEach(subset => {
      // 排除空集
      if (subset.length === 0) return
      // 把规格的组合拼接为路径字典的key
      const pathKey = subset.join(spliter)
      // 把结果添加到路径字典中即可
      if (pathMap[pathKey]) {
        // 已经存在该key了
        pathMap[pathKey].push(sku.id)
      } else {
        // 尚未存在，添加一个新的
        pathMap[pathKey] = [sku.id]
      }
    })
  })
  return pathMap
}

// 获取选中的所有的规格的值
const getSelectedValues = specs => {
  // result = [蓝色, undefinde, 10cm]
  const result = []
  specs.forEach((item, index) => {
    // 获取当前规格选中的标签
    const tag = item.values.find(tag => tag.selected)
    if (tag) {
      // 有选中的
      result[index] = tag.name
    } else {
      // 没有选中
      result[index] = undefined
    }
  })
  return result
}

// 更新每一个规格选项的禁用状态
const updateDisabledStatus = (specs, pathMap) => {
  // 把每一种规格的每一个选项遍历一屏
  specs.forEach((item, index) => {
    // 获取选中的值 result = [蓝色, 中国, 10cm]
    const result = getSelectedValues(specs)
    item.values.forEach(tag => {
      if (tag.selected) {
        // 如果标签本身就是选中的，不需要处理
        return
      } else {
        // 没有选中，就把当前标签的名称添加到选中的值中单独判断即可
        result[index] = tag.name
      }
      // 判断此时选中的值是否在字典中
      // 把选中的值拼接为字符串（字典的key）: 过滤掉undefined
      // const pathKey = result.filter(item => item).join(spliter)
      // 获取选中的值

      const seletedValues = result.filter(item => item)
      if (seletedValues.length > 0) {
        // 把选中的值拼接为字符串（字典的key）: 过滤掉undefined
        const pathKey = seletedValues.join(spliter)
        // 根据路径字典控制标签的禁用状态
        tag.disabled = !pathMap[pathKey]
      }
      // 根据pathKey去路径字典中判断是否存在
      // if (!pathMap[pathKey]) {
      //   // 此时的pathKey不在路径字典中，应该被禁用
      //   tag.disabled = true
      // }
    })
  })
}
const initSkuSeletedStatus = (skuId, specs, skus) => {
  // 获取当前sku信息
  const currentSku = skus.find(item => item.id === skuId)
  specs.forEach(item => {
    currentSku.specs.forEach(tagInfo => {
      // tagInfo表示应该被选中的规格信息
      const tag = item.values.find(tag => tag.name === tagInfo.valueName)
      if (tag) {
        // 该规格需要被选中
        tag.selected = true
      }
    })
  })
}
export default {
  name: 'GoodsSku',
  props: {
    specs: {
      type: Array,
      default: () => []
    },
    skus: {
      type: Array,
      default: () => []
    },
    skuId: {
      type: String,
      default: ''
    }
  },
  setup(props, { emit }) {
    const pathMap = usePathMap(props.skus)
    if (props.skuId) {
      initSkuSeletedStatus(props.skuId, props.specs, props.skus)
    }
    // console.log(pathMap)
    // const ret = getSelectedValues(props.specs)
    // console.log(ret)
    // 把每一个单独的选项判断一遍，并处理禁用状态
    updateDisabledStatus(props.specs, pathMap)
    // 控制选中和反选
    const toggle = (tag, list) => {
      // 判断标签是否为禁用状态
      if (tag.disabled) return
      // 当前的选中，其他的取消选中
      tag.selected = !tag.selected
      list.forEach(item => {
        if (item !== tag) {
          // 其他标签设置为不选中状态
          item.selected = false
        }
      })
      // 触发更新所有规格选项禁用状态的操作
      updateDisabledStatus(props.specs, pathMap)
      const result = getSelectedValues(props.specs)
      if (result.filter(item => item).length === props.specs.length) {
        const pathKey = result.join(spliter)
        const currentSkuId = pathMap[pathKey][0]
        const currentSku = props.skus.find(item => item.id === currentSkuId)
        const specesText = currentSku.specs.reduce((result, item) => result + item.name + ':' + item.valueName + '', '')
        const skuInfo = {
          skuId: currentSku.id,
          price: currentSku.price,
          oldPrice: currentSku.oldPrice,
          inventory: currentSku.inventory,
          specsText: specesText
        }
        emit('sku-info', skuInfo)
      }
    }
    return { toggle }
  }
}
</script>
<style scoped lang="less">
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;
  &.selected {
    border-color: @xtxColor;
  }
  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;
  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;
    dt {
      width: 50px;
      color: #999;
    }
    dd {
      flex: 1;
      color: #666;
      > img {
        width: 50px;
        height: 50px;
        .sku-state-mixin ();
      }
      > span {
        display: inline-block;
        height: 30px;
        line-height: 28px;
        padding: 0 20px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>
